#ifndef WORKER_MONITOR_TOPICS_H
#define WORKER_MONITOR_TOPICS_H

#include <rodos.h>

/*
 * Defining topics and messages for the worker and monitor protocol.
 */

//The messages are not used anymore. I left it for expansions in future versions.
enum wmMessageType
{
	//Meaningless message, shouldn't be published, just for initialization
	MEANINGLESS,

	//Broadcast message to request an answer. Fields: ignored
	PING,

	//Answer to PING. Fields: nodeNumber = this->nodeID, genData = (isWorker ? 1 : 0)
	PONG,

	//Broadcast message and response message. Whether it is a broadcast or response message is
	//decided by the nodeNumber. If nodenumber == -1 it's a broadcast message to which the worker only
	//should respond. If nodenumber != -1 nodenumber is the id of the answering worker.
	IDENTIFY_WORKER,

	//Make a node a worker
	SET_WORKER,

	//Make a node a monitor
	SET_MONITOR,

	//Sets the operationmode
	SET_MODE,
	
	//Sets the time between two StatusData messages
	SET_STATUS_PERIOD,

	//Commands the worker to send or not send StatusData. genData != 0 => send StatusData else don't send
	SET_STATUS_SEND
};

//Enumeration for distinguishing between different modes of operation
//Created because different modes of operation were mentioned in the description
enum operationMode {
	NORMAL
};

//Contains a full messages issued via the nmx topic
struct WMMessage
{
	wmMessageType messageType;

	//A node ID. Meaning depends on the message type.
	long nodeNumber;

	//A data field. Meaning depends on the message type.
	long genData;
};

//Contains status data to be published via the satelliteStatus topic
struct StatusData {
	double posX;
	double posY;
	double posZ;

	double temperature;
};


//defined here so it does not have to be changed in the GUI
#define MAX_NUM_STATUS_DATA_FIELDS 16

//Defines possible data types
enum DataType { DTCHAR, DTBOOL, DTSHORT, DTLONG, DTLONGLONG, DTFLOAT, DTDOUBLE, DTSTRING };

//We do this to make editing the StatusData topic easier so there is no need to edit the code when there
//is the need to add or remove a field from the StatusData struct
struct DataDescription {
	DataType type[MAX_NUM_STATUS_DATA_FIELDS];
	char* names[MAX_NUM_STATUS_DATA_FIELDS];
};


//Usage of the struct defined above using the current setup
static DataDescription housekeepingData = {
	{DTDOUBLE, DTDOUBLE, DTDOUBLE, DTDOUBLE},
	{"PosX (in km)","PosY (in km)","PosZ (in km)","Temperature (in °C)"}
};

//Topic for workers and monitors to exchange (Node Message eXchange)
extern Topic<WMMessage, -1> nmx;

//Topic for the active workers
extern Topic<long, -1> workerAlive;

//Topic for status information
extern Topic<StatusData, -1> satelliteStatus;

#endif //WORKER_MONITOR_TOPICS
